//
//  numerics.h
//  utilities
//
//  Created by Sam Jaffe on 12/30/12.
//  Copyright (c) 2012 Sam Jaffe. All rights reserved.
//

#pragma once

template <typename _Num>
struct __Number_base;

template <class _Num>
struct Number;

using Integer = Number<int>;
using Double = Number<double>;
using Float = Number<float>;
using Long = Number<long long>;
using Short = Number<short>;

template <typename _Num>
struct __Number_base {
    _Num data;

    __Number_base() {
        
    }
    
    __Number_base(_Num init) : data(init) {
        
    }
    
    ~__Number_base() {
        
    }
    
    
    __Number_base operator +(const __Number_base& rhs) const {
        return __Number_base(data + rhs);
    }
    
    
    __Number_base operator -(const __Number_base& rhs) const {
        return __Number_base(data - rhs);
    }
    
    
    __Number_base operator *(const __Number_base& rhs) const {
        return __Number_base(data * rhs);
    }
    
    
    __Number_base operator /(const __Number_base& rhs) const {
        return __Number_base(data / rhs);
    }
    
    
    __Number_base operator -() const {
        return __Number_base(-data);
    }
    
    operator _Num() {
        return data;
    }
};

template <class _Num>
struct Number : __Number_base<_Num> {
    Number() {
        
    }
    
    Number(const _Num n) :
    __Number_base<_Num>(n) {
        
    }
    
    Number(const __Number_base<_Num>& other) :
    __Number_base<_Num>(other) {
        
    }
    
    ~Number() {
        
    }
};

template <>
struct Number<int> : __Number_base<int> {
    Number<int>() {
        
    }
    
    Number<int>(const int init) :
    __Number_base<int>(init) {
        
    }
    
    Number<int>(const __Number_base<int>& other) :
    __Number_base<int>(other) {
        
    }
    
    ~Number<int>() {
        
    }
    
    Number<int> operator >>(const Number<int>& rhs) const {
        return Number<int>(data >> int(rhs));
    }
    
    
    Number<int> operator <<(const Number<int>& rhs) const {
        return Number<int>(data << int(rhs));
    }
    
    
    Number<int> operator -() const {
        return Number<int>(-data);
    }
    
    operator int() const {
        return data;
    }
};

template <class _Num, _Num lower, _Num upper>
struct BoundNumber : public Number<_Num> {
    
}
